package org.example.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.example.mapper.*;
import org.example.pojo.Category;
import org.example.pojo.Goods;
import org.example.pojo.Top10Vo;
import org.example.service.EchartsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

@Service
@Slf4j
public class EchartsServiceImpl implements EchartsService {
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private CategoryMapper categoryMapper;

    /**
     * 获取库存前十的商品信息
     *
     * @return
     */
    @Override
    public Top10Vo Top10Inventory() {
        // 获取库存前十的商品信息
        List<Goods> goodsList = goodsMapper.getTop10Name();
        // 获取商品名称
        List<String> goodsName = goodsList.stream().map(Goods::getGoodsName).toList();
        // 获取库存数量
        List<Integer> goodsAmount = goodsList.stream().map(Goods::getQuantity).toList();
        return Top10Vo.builder()
                .goodsName(goodsName)
                .goodsAmount(goodsAmount)
                .build();
    }

    /**
     * 获取商品分类占比
     *
     * @return
     */
    @Override
    public Object categoryProportion(String timeRange) {
        // 如果传来的值为month，就获取本月的开始时间和结束时间，如果为week就获取本周的开始时间和结束时间，如果为year就获取本年的开始时间和结束时间
        LocalDateTime start = null;
        LocalDateTime end = null;
        switch (timeRange) {
            case "month":
                start = getStartOfMonth();
                end = getEndOfMonth();
                break;
            case "week":
                start = getStartOfWeek();
                end = getEndOfWeek();
                break;
            case "year":
                start = getStartOfYear();
                end = getEndOfYear();
                break;
            default:
                break;
        }
        // 获取所有商品分类
        List<Category> categoryList = categoryMapper.getCategorylist();
        // 获取所有商品
        List<Goods> goodsList = goodsMapper.getAllGoods(start, end);

        // 统计每种分类的商品数量
        Map<String, Integer> map = new HashMap<>();
        for (Category category : categoryList) {
            int count = 0;
            for (Goods goods : goodsList) {
                if (goods.getCategoryId() == category.getId()) {
                    count++;
                }
            }
            map.put(category.getCategoryName(), count);
        }
        // 将map中的数据转化为json格式 [｛value:count,name:""｝,｛value:count,name:""｝]
        List<Map<String, Object>> list = map.entrySet().stream().map(entry -> {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("value", entry.getValue());
            map1.put("name", entry.getKey());
            return map1;
        }).toList();
        return list;
    }


    @Autowired
    private InventoryMapper inventoryMapper;
    @Autowired
    private OrderMapper orderMapper;

    /**
     * 获取商品概览信息
     *
     * @return
     */
    @Override
    public Map<String, Integer> overview() {
        // 获取库存商品总数
        Integer totalProducts = inventoryMapper.countQuantity();
        // 获取库存预警数
        Integer warningCount = inventoryMapper.warningCount();
        // 获取本月入库商品数
        // 获取本月的开始和结束时间
        LocalDateTime startOfMonth = getStartOfMonth();
        LocalDateTime endOfMonth = getEndOfMonth();
        // 查询订单表中已入库状态的订单所关联的订单详情表的所有入库数
        Integer monthlyInbound = orderMapper.countQuantityIn(startOfMonth, endOfMonth);
        // 获取本月的出库商品数
        Integer monthlyOutbound = orderMapper.countQuantityOut(startOfMonth, endOfMonth);

        return Map.of(
                "totalProducts", totalProducts,
                "warningCount", warningCount,
                "monthlyInbound", monthlyInbound,
                "monthlyOutbound", monthlyOutbound
        );
    }

    /**
     * 获取库存商品趋势
     *
     * @param type
     * @param startTime
     * @param endTime
     */
    @Override
    public Map<String, Object> trend(String type, String startTime, String endTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate start = LocalDate.parse(startTime, formatter);
        LocalDate end = LocalDate.parse(endTime, formatter);
        // 获取从开始时间到结束时间的日期集合
        List<LocalDate> dateList = new ArrayList<>();
        while (!start.isAfter(end)) {
            dateList.add(start);
            start = start.plusDays(1);
        }
        List<Integer> list = new ArrayList<>();
        dateList.forEach(date -> {
            switch (type) {
                case "in":
                    LocalDateTime[] startAndEndOfDay = getStartAndEndOfDay(date);
                    list.add(orderMapper.countQuantityIn(startAndEndOfDay[0], startAndEndOfDay[1]));
                    break;
                case "out":
                    LocalDateTime[] startAndEndOfDay2 = getStartAndEndOfDay(date);
                    list.add(orderMapper.countQuantityOut(startAndEndOfDay2[0], startAndEndOfDay2[1]));
                    break;
                default:
                    break;
            }
        });
        int total = 0;
        for (Integer integer : list) {
            if (integer != null) {  // 检查元素是否为 null
                total += integer;
            } else {
                total += 0;  // 如果为 null，视为 0 处理
            }
        }
        return Map.of(
                "dates", dateList,
                "values", list,
                "total", total
        );
    }


    /**
     * 获取指定日期的开始时间和结束时间
     *
     * @param date
     * @return
     */
    public LocalDateTime[] getStartAndEndOfDay(LocalDate date) {
        // 获取当天的开始时间（00:00:00）
        LocalDateTime startOfDay = date.atStartOfDay();
        // 获取当天的结束时间（23:59:59.999999999）
        LocalDateTime endOfDay = date.atTime(23, 59, 59, 999999999);
        // 返回开始时间和结束时间
        return new LocalDateTime[]{startOfDay, endOfDay};
    }

    /**
     * 获取本月的开始时间和结束时间
     *
     * @return
     */
    public LocalDateTime getStartOfMonth() {
        return LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth()).withHour(0).withMinute(0).withSecond(0);
    }

    public LocalDateTime getEndOfMonth() {
        return LocalDateTime.now().with(TemporalAdjusters.lastDayOfMonth()).withHour(23).withMinute(59).withSecond(59);
    }

    /**
     * 获取本周的开始时间和结束时间
     */
    public LocalDateTime getStartOfWeek() {
        return LocalDateTime.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).withHour(0).withMinute(0).withSecond(0);
    }

    public LocalDateTime getEndOfWeek() {
        return LocalDateTime.now().with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)).withHour(23).withMinute(59).withSecond(59);
    }

    /**
     * 获取本年的开始时间和结束时间
     */
    public LocalDateTime getStartOfYear() {
        return LocalDateTime.now().with(TemporalAdjusters.firstDayOfYear()).withHour(0).withMinute(0).withSecond(0);
    }

    public LocalDateTime getEndOfYear() {
        return LocalDateTime.now().with(TemporalAdjusters.lastDayOfYear()).withHour(23).withMinute(59).withSecond(59);
    }
}
